home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / DevDisk 65 (1989)(DevWare PD).zip / DevDisk 65 (1989)(DevWare PD).adf / prosuite / fileio.c < prev    next >
C/C++ Source or Header  |  1990-07-11  |  15KB  |  483 lines

  1.  
  2. /* *** fileio.c *************************************************************
  3.  *
  4.  * File IO Suite  --  Primary FileIO Requester Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  15.  * All copyright notices and all file headers must be retained intact.
  16.  * The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  17.  * resultant object code may be included in any software product.  However, no 
  18.  * portion of the source listings or documentation of the Amiga Programmer's 
  19.  * Suite Book 1 may be distributed or sold for profit or in a for-profit 
  20.  * product without the written authorization of the author, RJ Mical.
  21.  * 
  22.  * HISTORY      NAME            DESCRIPTION
  23.  * -----------  --------------  --------------------------------------------
  24.  * 20 Oct 87    - RJ            Added RENAME_RAMDISK to fix what seems to 
  25.  *                              be a bug in either AmigaDOS or Workbench.
  26.  * 26 Aug 87    RJ              Added test for 0 GadgetID at end of 
  27.  *                              GetFileIOName()
  28.  * 4 Feb 87     RJ              Real release
  29.  * 12 Aug 86    RJ >:-{)*       Prepare (clean house) for release
  30.  * 3 May 86     =RJ Mical=      Fix prop gadget for both 1.1 and 1.2
  31.  * 1 Feb 86     =RJ Mical=      Created this file.
  32.  *
  33.  * *********************************************************************** */
  34.  
  35.  
  36. #define FILEIO_SOURCEFILE
  37. #include "fileio.h"
  38.  
  39.  
  40. /* These routines can be found in filesupp.c */
  41. extern HandleGadget();
  42. extern StartOpenRequester();
  43. extern DiskInserted();
  44. extern PropMouseMoves();
  45.  
  46.  
  47.  
  48. /* *** GetFileIOSupport() ***************************************************
  49.  * 
  50.  * NAME
  51.  *     GetFileIOSupport  --  Allocate and initialize a FileIOSupport structure
  52.  * 
  53.  * 
  54.  * SYNOPSIS
  55.  *     struct FileIOSupport *GetFileIOSupport();
  56.  * 
  57.  * 
  58.  * FUNCTION
  59.  *     Allocates and initializes a FileIOSupport structure for use with
  60.  *     calls to GetFileIOName().
  61.  * 
  62.  *     You may want to further initialize the structure before calling
  63.  *     GetFileIOName().  Refer to the FileIO documentation for more
  64.  *     information.
  65.  * 
  66.  *     When you're done with the structure, call ReleaseFileIO().
  67.  * 
  68.  * 
  69.  * INPUTS
  70.  *     None
  71.  * 
  72.  * 
  73.  * RESULT
  74.  *     If all goes well, returns the address of a FileIOSupport structure.
  75.  *     If anything goes wrong (usually out of memory), returns NULL.
  76.  * 
  77.  * 
  78.  * EXAMPLE
  79.  *     struct FileIOSupport *fileio;
  80.  *     fileio = GetFileIOSupport();
  81.  *     GetFileIOName(fileio, window);
  82.  *     ReleaseFileIO(fileio);
  83.  * 
  84.  * 
  85.  * BUGS
  86.  *     None known
  87.  * 
  88.  * 
  89.  * SEE ALSO
  90.  *     GetFileIOName(), ReleaseFileIO()
  91.  */
  92. struct FileIOSupport *GetFileIOSupport()
  93. {
  94.     struct FileIOSupport *fileio;
  95.  
  96.     if (fileio = (struct FileIOSupport *)AllocMem(
  97.             sizeof(struct FileIOSupport), MEMF_CLEAR))
  98.         {
  99.         /* Anything special to initialize? */
  100.         SetFlag(fileio->Flags, USE_VOLUME_NAMES | RENAME_RAMDISK);
  101.         }
  102.     return(fileio);
  103. }
  104.  
  105.  
  106.  
  107. /* *** GetFileIOName() ******************************************************
  108.  * 
  109.  * NAME
  110.  *     GetFileIOName  --  Gets a file name for input/output from the user
  111.  * 
  112.  * 
  113.  * SYNOPSIS
  114.  *     BOOL GetFileIOName(FileIO, Window);
  115.  * 
  116.  * 
  117.  * FUNCTION
  118.  *     This routine creates a filename requester which allows the user
  119.  *     to browse through the AmigaDOS filesystem and select one of
  120.  *     the filenames found there.
  121.  * 
  122.  *     The FileIO argument is a pointer to a FileIOSupport structure,
  123.  *     which is allocated and initialized for you via a call to 
  124.  *     GetFileIOSupport().
  125.  *     You may preset the FileIO parameters before calling this routine, 
  126.  *     or you may leave them set at their default values.  See the FileIO
  127.  *     documentation for complete details.
  128.  * 
  129.  *     The Window argument is the pointer to the window structure returned
  130.  *     by a call to Intuition's OpenWindow() function.  As this routine
  131.  *     opens a requester and requesters open in windows, you must have
  132.  *     already opened a window before calling this routine, even if it's
  133.  *     a window opened for no other purpose than to call this routine.
  134.  * 
  135.  *     This routine returns a BOOL value of TRUE or FALSE, depending on
  136.  *     whether the user chose to accept or cancel the filename selection 
  137.  *     operation.  If TRUE, the filename selected by the user can be
  138.  *     found in the FileIO structure FileName[] field.  This filename
  139.  *     will have all leading and trailing blanks removed (in case the
  140.  *     user typed in a filename with extraneous spaces).  Likewise,
  141.  *     the pathname to the disk and drawer can be found in the text
  142.  *     fields DiskName[] and DrawerName[].  You can construct 
  143.  *     the pathname using these text strings.  Also, you can call 
  144.  *     BuildFileIOPathname() to build the pathname automatically.
  145.  * 
  146.  *     There's a *lot* more to be said about this function.  Please 
  147.  *     read the documentation.
  148.  * 
  149.  *     NOTE:  This routine is not re-entrant.  What this means 
  150.  *     is that if you have created a program that has more than one task,
  151.  *     this routine cannot be called by more than one task at a time.
  152.  *     This is not a problem for the grand majority of programs.
  153.  *     But if you have some application that would require calling this 
  154.  *     routine asynchronously from multiple tasks, you'll have to 
  155.  *     implement some quick semaphore arrangement to avoid collisions.
  156.  *     No big deal, actually.  See Exec semaphores for everything you need.
  157.  * 
  158.  * 
  159.  * INPUTS
  160.  *     FileIO = pointer to a FileIOSupport structure, as allocated
  161.  *         via a call to GetFileIOSupport()
  162.  *     Window = pointer to a Window structure, as created via a call
  163.  *         to Intuition's OpenWindow()
  164.  * 
  165.  * 
  166.  * RESULT
  167.  *     TRUE if the user decided that the filename selection was successful,
  168.  *     FALSE if the user chose to cancel the operation
  169.  * 
  170.  * 
  171.  * EXAMPLE
  172.  *     if (GetFileIOName(fileio, window))
  173.  *         ProcessFileName(&fileio->FileName[0]);
  174.  * 
  175.  * 
  176.  * BUGS
  177.  *     None known, though there could be some, and the disk selection
  178.  *     subsystem logic is not perfectly polished (though it's believed 
  179.  *     to be bug-free).
  180.  * 
  181.  * 
  182.  * SEE ALSO
  183.  *     BuildFileIOPathname(), GetFileIOSupport(), ReleaseFileIO()
  184.  */
  185. BOOL GetFileIOName(fileio, window)
  186. struct FileIOSupport *fileio;
  187. struct Window *window;
  188. {
  189.     UBYTE *newtext;
  190.  
  191.     if ((fileio == NULL) || (window == NULL)) return(FALSE);
  192.  
  193.     OpenSaveLock = CurrentDir(NULL);
  194.     CurrentDir(OpenSaveLock);
  195.     fileio->DOSLock = OpenSaveLock;
  196.  
  197.     /* Get easily-accessible copies of the values that are referenced 
  198.      * most often
  199.      */
  200.     OpenReq = &OpenReqSupport.Requester;
  201.     OpenReqWindow = OpenReqSupport.Window = window;
  202.     OpenReqFileIO = fileio;
  203.  
  204.     /* Set up the DoRequest() handlers */
  205.     OpenReqSupport.GadgetHandler = HandleGadget;
  206.     OpenReqSupport.StartRequest = StartOpenRequester;
  207.     OpenReqSupport.NewDiskHandler = DiskInserted;
  208.     OpenReqSupport.MouseMoveHandler = PropMouseMoves;
  209.  
  210.     /* Init the string gadget buffers */
  211.     OpenNameTextInfo.Buffer = &fileio->FileName[0];
  212.     OpenDrawerTextInfo.Buffer = &fileio->DrawerName[0];
  213.     OpenDiskTextInfo.Buffer = &fileio->DiskName[0];
  214.  
  215.     /* Initialize the requester title */
  216.     if ((ReqTitleText.IText = fileio->ReqTitle) == NULL)
  217.         ReqTitleText.IText = DefaultReqTitle;
  218.     ReqTitleText.LeftEdge
  219.         = (OPEN_WIDTH - IntuiTextLength(&ReqTitleText)) >> 1;
  220.  
  221.     /* If this fileio doesn't have valid filenames,
  222.      * then refresh the whole thing
  223.      */
  224.     if (FlagIsClear(fileio->Flags, GOOD_FILENAMES))
  225.         {
  226.         ResetNameText(TRUE);
  227.         ResetDrawerText(TRUE);
  228.         BuildVolumeTable(fileio);
  229.         CopyString(&OpenReqFileIO->DiskName[0], CurrentVolumeName());
  230.         }
  231.  
  232.     ResetNameText(FALSE);
  233.     ResetDrawerText(FALSE);
  234.     ResetDiskText(FALSE);
  235.  
  236.     StuffSelectNames(0);
  237.     InitOpenProp(TRUE);
  238.  
  239.     /* Reset the double-click time variables */
  240.     OpenClickSeconds = OpenClickMicros = 0;
  241.  
  242.  
  243.     /* And now, do that requester. */
  244.     DoRequest(&OpenReqSupport);
  245.     /* Back, eh?  Wasn't that easy? */
  246.  
  247.  
  248.     if (FlagIsSet(fileio->Flags, LOCK_GOTTEN))
  249.         {
  250.         UnLock(fileio->DOSLock);
  251.         ClearFlag(fileio->Flags, LOCK_GOTTEN);
  252.         }
  253.  
  254.     CurrentDir(OpenSaveLock);
  255.     OpenReqFileIO = NULL;
  256.  
  257.     /* Strip any excess leading and trailing blanks off the final name */
  258.     newtext = StripOuterSpace(&fileio->FileName[0], " ");
  259.     CopyString(&fileio->FileName[0], newtext);
  260.  
  261.     if ((OpenReqSupport.SelectedGadgetID)
  262.             && (OpenReqSupport.SelectedGadgetID != OPENGADGET_CANCEL))
  263.         return(TRUE);
  264.     return(FALSE);
  265. }
  266.  
  267.  
  268.  
  269. /* *** BuildFileIOPathname() ************************************************
  270.  * 
  271.  * NAME
  272.  *     BuildFileIOPathname  --  Build a file pathname using a FileIO struct
  273.  * 
  274.  * 
  275.  * SYNOPSIS
  276.  *     BuildFileIOPathname(FileIOSupport, Buffer);
  277.  * 
  278.  * 
  279.  * FUNCTION
  280.  *     Builds the text for a pathname using the FileName[], DrawerName[] and
  281.  *     DiskName[] fields of the specified FileIOSupport structure
  282.  *     after the support structure has been used in a successful call
  283.  *     to GetFileIOName().  Writes the text into the Buffer.
  284.  * 
  285.  * 
  286.  * INPUTS
  287.  *     FileIOSupport = the address of a FileIOSupport structure
  288.  *     Buffer = address of the buffer to receive the file pathname
  289.  * 
  290.  * 
  291.  * RESULT
  292.  *     None
  293.  * 
  294.  * 
  295.  * SEE ALSO
  296.  *     GetFileIOName()
  297.  */
  298. VOID BuildFileIOPathname(fileio, buffer)
  299. struct FileIOSupport *fileio;
  300. UBYTE *buffer;
  301. {
  302.     StripOuterSpace(&fileio->DiskName[0], " ");
  303.     StripOuterSpace(&fileio->DrawerName[0], " ");
  304.     StripOuterSpace(&fileio->FileName[0], " ");
  305.  
  306.     CopyString(buffer, &fileio->DiskName[0]);
  307.     if (StringLength(&fileio->DrawerName[0]))
  308.         {
  309.         ConcatString(buffer, &fileio->DrawerName[0]);
  310.         ConcatString(buffer, "/");
  311.         }
  312.     ConcatString(buffer, &fileio->FileName[0]);
  313. }
  314.  
  315.  
  316.  
  317. /* *** AddFileIOName() ******************************************************
  318.  * 
  319.  * NAME
  320.  *     AddFileIOName  --  Add a file name to the names in a FileIOSupport
  321.  * 
  322.  * 
  323.  * SYNOPSIS
  324.  *     AddFileIOName(FileIOSupport, FileName);
  325.  * 
  326.  * 
  327.  * FUNCTION
  328.  *     This routine adds a file name to the list of file names currently 
  329.  *     in the specified FileIOSupport structure.  The next time the 
  330.  *     FileIOSupport structure is used for a call to GetFileIOName(), the 
  331.  *     new file name will apppear alphabetized in with the other file names.  
  332.  *     
  333.  *     This routine will most often be used after a call to GetFileIOName() 
  334.  *     or some other routine where the user is allowed to specify the name 
  335.  *     of a file to be opened for output.  If the file is opened 
  336.  *     successfully, this routine will make sure that the name of the file 
  337.  *     is in the FileIOSupport structure.  This is important if the output 
  338.  *     file has been newly created; otherwise, without calling this 
  339.  *     routine, the next time the FileIOSupport structure is used the new 
  340.  *     file name would not appear even though the file exists.  If the name 
  341.  *     is already in the list when you call AddFileIOName() then nothing 
  342.  *     happens.  This allows you to call AddFileIOName() without worrying 
  343.  *     about duplicate name redundancy.
  344.  *     
  345.  *     Here's a typical sequence of events leading up to a call to 
  346.  *     AddFileIOName():
  347.  *     
  348.  *         First, get a FileIOSupport structure:
  349.  *             fileio = GetFileIOSupport(...);
  350.  *     
  351.  *         When the user wants to write data, use GetFileIOName()
  352.  *         to provide a convenient and consistent interface to
  353.  *         the filesystem:
  354.  *             goodfile = GetFileIOName(...);
  355.  *     
  356.  *         If the user has selected a name for output (in this example,
  357.  *         goodfile will equal TRUE if the user selected a name), then
  358.  *         open the file (possibly creating it) and then call 
  359.  *         AddFileIOName() to make sure the name is in the FileIOSupport
  360.  *         structure's list:
  361.  *             if (goodfile)
  362.  *                 {
  363.  *                 UBYTE filename[80];
  364.  *                 
  365.  *                 BuildFileIOPathname(fileio, &filename[0]);
  366.  *                 ... open filename, write it, close it ...
  367.  *                 if (filename opened successfully)
  368.  *                     AddFileIOName(fileio, &filename[0]);
  369.  *                 }
  370.  * 
  371.  * 
  372.  * INPUTS
  373.  *     FileIOSupport = the address of a FileIOSupport structure
  374.  *     FileName = the address of null-terminated text that is
  375.  *         either a simple file name or a valid AmigaDOS pathname.
  376.  * 
  377.  * 
  378.  * RESULT
  379.  *     None
  380.  * 
  381.  * 
  382.  * SEE ALSO
  383.  *     GetFileIOName()
  384.  *     GetFileIOSupport()
  385.  */
  386. VOID AddFileIOName(fileio, filename)
  387. struct FileIOSupport *fileio;
  388. UBYTE *filename;
  389. {
  390.     SHORT index, i, length;
  391.     struct Remember *remember, *oldremember;
  392.     UBYTE *nextentry;
  393.     struct Remember *namekey;
  394.  
  395.     /* Does the filename start with a volume name?  If so, skip over it */
  396.     index = IndexString(filename, ":");
  397.     if (index >= 0) filename += index + 1;
  398.  
  399.     /* Does the filename start with a directory name?  If so, skip over it */
  400.     do 
  401.         {
  402.         index = IndexString(filename, "/");
  403.         if (index >= 0) filename += index + 1;
  404.         }
  405.     while (index >= 0);
  406.  
  407.     if (*filename == 0) return;
  408.  
  409.     /* Here, filename points to what is presumed to be a valid file name.
  410.      * If it's found among the FileIOSupport's names, exit.
  411.      * If it's not found in the list, add it.
  412.      *
  413.      * The current file names are stored in the fileio's Remember list.
  414.      */
  415.     remember = fileio->NameKey;
  416.     oldremember = NULL;
  417.     while (remember)
  418.         {
  419.         i = CompareUpperStrings(filename, remember->Memory);
  420.         if (i < 0) goto ADD_FILENAME;
  421.         if (i == 0) return;
  422.         oldremember = remember;
  423.         remember = remember->NextRemember;
  424.         }
  425.  
  426. ADD_FILENAME:
  427.     /* Name not on list, so add it now */
  428.     length = StringLength(filename);
  429.  
  430.     namekey = NULL;
  431.     if (nextentry = AllocRemember(&namekey, length + 1 + 1, NULL))
  432.         {
  433.         CopyString(nextentry, filename);
  434.         *(nextentry + length + 1) = 0;
  435.         if (oldremember) oldremember->NextRemember = namekey;
  436.         else fileio->NameKey = namekey;
  437.         /* This assignment is valid whether or not remember is NULL */
  438.         namekey->NextRemember = remember;
  439.         fileio->NameCount++;
  440.         }
  441. }
  442.  
  443.  
  444.  
  445. /* *** ReleaseFileIO() ******************************************************
  446.  * 
  447.  * NAME
  448.  *     ReleaseFileIO  --  Release the FileIO structure and all local memory
  449.  * 
  450.  * 
  451.  * SYNOPSIS
  452.  *     ReleaseFileIO(FileIO);
  453.  * 
  454.  * 
  455.  * FUNCTION
  456.  *     Releases the FileIO structure by freeing all local memory attached
  457.  *     to the structure and then freeing the structure itself.
  458.  * 
  459.  * 
  460.  * INPUTS
  461.  *     FileIO = the address of a FileIO structure
  462.  * 
  463.  * 
  464.  * RESULT
  465.  *     None
  466.  * 
  467.  * 
  468.  * SEE ALSO
  469.  *     GetFileIOSupport()
  470.  */
  471. VOID ReleaseFileIO(fileio)
  472. struct FileIOSupport *fileio;
  473. {
  474.     if (fileio)
  475.         {
  476.         FreeRemember(&fileio->VolumeKey, TRUE);
  477.         FreeRemember(&fileio->NameKey, TRUE);
  478.         FreeMem(fileio, sizeof(struct FileIOSupport));
  479.         }
  480. }
  481.  
  482.  
  483.